package com.starblink.web.core

import android.app.AlertDialog
import android.graphics.Bitmap
import android.net.Uri
import android.net.http.SslError
import android.os.Build
import android.webkit.*
import com.starblink.android.basic.network.base.BaseApiClient
import com.starblink.android.basic.widget.ConfirmDialog
import com.starblink.basic.log.SKLogger
import com.starblink.basic.style.R
import com.starblink.basic.util.ActivityStackManage
import com.starblink.web.util.GuangWebViewPool
import com.starblink.web.util.WebCacheUtil
import java.net.URLDecoder

class BaseWebViewClient(private val mWebSettings: WebSettings) : WebViewClient() {
    private val TAG = "GuangWebView"
    var mListener: GuangWebView.OnWebChangeListener? = null
    var ifUseCache: Boolean = true
    //记录埋点的URL 包括重定向的URL在内
    var loadSpmUrlMap:HashMap<String,Map<String,String>> = hashMapOf()
    override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
        SKLogger.d(TAG, "onPageStarted --- $url")
        mListener?.onWebLoadStart(url)
    }

    override fun onPageFinished(view: WebView?, url: String?) {
        try {
            if (!mWebSettings.loadsImagesAutomatically) {
                mWebSettings.loadsImagesAutomatically = true
            }
            SKLogger.d(TAG, "onPageFinished --- $url")
            if (url == "about:blank") {
                //释放历史页面
                view?.clearHistory()
                view?.stopLoading()
                if (view is GuangWebView) {
                    //回收webview
                    GuangWebViewPool.getInstance().recycle(view)
                }
            } else {
                mListener?.onWebLoadFinish(url)

                //埋点上报
                var params = loadSpmUrlMap[url] ?: loadSpmUrlMap[URLDecoder.decode(url, "UTF-8")]
                if (params == null && url != null && url.contains("/?")) {
                    SKLogger.w(TAG, "链接存在--- /? --- $url")
                    val targetUrl = url.replace("/?", "?")
                    params = loadSpmUrlMap[targetUrl] ?: loadSpmUrlMap[URLDecoder.decode(
                        targetUrl,
                        "UTF-8"
                    )]
                }
                params?.let {
                    mListener?.onWebLoadStatus(it)
                    SKLogger.w(TAG, "H5上报--- 状态 $it")

                    //上报后删除
                    loadSpmUrlMap.remove(url)
                    loadSpmUrlMap.remove(URLDecoder.decode(url, "UTF-8"))
                    val targetUrl = url?.replace("/?", "?")
                    loadSpmUrlMap.remove(targetUrl)
                    loadSpmUrlMap.remove(URLDecoder.decode(targetUrl, "UTF-8"))
                }
            }
        }catch (e:Exception){
            SKLogger.e(TAG, "onPageFinished --- $e")
        }
    }

    //在当前的webview中跳转到新的url
    override fun shouldOverrideUrlLoading(view: WebView, url: String?): Boolean {
        mListener?.onInnerLinkChecked()

        SKLogger.d(TAG, "跳转加载的H5地址 $url")
        if (view.url!!.startsWith(BaseApiClient.getPrivacyUrl()) || view.url!!.startsWith(
                BaseApiClient.getTermsUrl()
            )
        ) {
            //隐私政策和用户协议页面 拦截超链接跳转
            return true
        }

        val scheme = Uri.parse(url).scheme ?: return false
        when (scheme) {
            "http", "https" -> view.loadUrl(url!!)
            // 处理其他协议
            //"weixin" ->  {}
            //"alipays" ->  {}
        }
        return true //true拦截 false不拦截
    }

    override fun onReceivedError(
        view: WebView?,
        request: WebResourceRequest?,
        error: WebResourceError?
    ) {
        super.onReceivedError(view, request, error)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            SKLogger.w(
                TAG,
                "H5 加载报错 ${request?.url} --- ${error?.description} --- ${error?.errorCode}"
            )
        }
        mListener?.onWebLoadError()
    }

    override fun onReceivedHttpError(
        view: WebView?,
        request: WebResourceRequest?,
        errorResponse: WebResourceResponse?
    ) {
        super.onReceivedHttpError(view, request, errorResponse)

        val loadUrl: String = request?.url.toString()
        if (loadUrl.endsWith("favicon.ico")) {
            //所谓favicon，即Favorites Icon的缩写，是指显示在浏览器收藏夹、地址栏和标签标题前面的个性化图标。 以图标的方式区别不同的网站
            //favicon.ico 不是必要的，当您使用浏览器浏览不同站点时，浏览器将自动发送请求。 如果您的浏览器收到有效 favicon.ico 文件，将显示此图标。 如果未收到，则不会显示特殊图标，会报404错误，并且会记录到错误日志中，所以最好的设置
            return
        }
        mListener?.let {listener->
            //查找是否存在需要上报加载的H5地址
            if(loadSpmUrlMap.containsKey(loadUrl)){
                var location= ""
                if (errorResponse?.responseHeaders?.containsKey("Location") == true) {
                    location = errorResponse.responseHeaders["Location"].toString()
                }
                val params = mapOf("url" to loadUrl,"code" to "${errorResponse?.statusCode}",
                    "location" to location)
                loadSpmUrlMap.put(loadUrl,params)
            }
        }
        SKLogger.w(
            TAG,
            "onReceivedHttpError--- 状态 ${errorResponse?.statusCode} --- $loadUrl"
        )
    }

    override fun onReceivedSslError(
        view: WebView?,
        handler: SslErrorHandler?,
        error: SslError?
    ) {
        ConfirmDialog.Builder(ActivityStackManage.currentActivity())
            .setMessage("SSL certificate validation failed.\n" +
                    "Continue anyway?")
            .setCancelButton(R.string.cancel) { dialog, _ ->
                dialog.dismiss()
                handler?.cancel()
            }
            .setSureButton(R.string.continue_) { dialog, _ ->
                dialog.dismiss()
                handler?.proceed()
            }
            .setCanCancel(false)
            .create().show()
    }

    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        //拦截资源加载
        var webResourceResponse: WebResourceResponse? =
            if (ifUseCache) WebCacheUtil.shouldInterceptRequest(view, request) else null
        if (webResourceResponse == null) {
            webResourceResponse = super.shouldInterceptRequest(view, request)
        }
        return webResourceResponse
    }

    /**
     * @param view 需要清理的WebView。
     * @param detail 退出的原因。。
     * @return true 如果主机应用程序处理了进程退出的情况，否则，如果渲染进程崩溃，应用程序将崩溃，或者如果渲染进程被系统杀死，则应用程序将被终止。
     */
    override fun onRenderProcessGone(
        view: WebView?,
        detail: RenderProcessGoneDetail?
    ): Boolean {
        if (view is GuangWebView) {
            //解决部分机型Chrome内核偶现预加载Render Process
            return true
        }
        return super.onRenderProcessGone(view, detail)
    }

    fun putSpmLoadUrl(loadUrl:String){
        //默认所有加载的H5地址为code 200
        val params = mapOf("url" to loadUrl,"code" to "200")
        loadSpmUrlMap[loadUrl]=params
    }
    fun clearSpmLoadUrl(){
        loadSpmUrlMap.clear()
    }
}